<?php
require_once __DIR__ . '/../vendor/autoload.php';

$container = new DI\Container();

$container->whoops = new \Whoops\Run;
$container->whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler());
$container->whoops->register();

$container->log = new \Monolog\Logger('doc');
$container->log->pushHandler(new \Monolog\Handler\StreamHandler(__DIR__ . '/debug.json', \Monolog\Logger::DEBUG));

$container->github=new \Github\Client(new \Github\HttpClient\Builder(\Http\Adapter\Guzzle6\Client::createWithConfig(['verify'=>false])));

$container->latte=new \Latte\Engine();
$container->latte->setTempDirectory(__DIR__ . '/../runtime/tmpcache');

$container->cache = new \Doctrine\Common\Cache\FilesystemCache(__DIR__ . '/../runtime/cache');

$container->config=new \Noodlehaus\Config(__DIR__ . '/../config.ini', new \Noodlehaus\Parser\Ini);

$container->dispatcher = \FastRoute\simpleDispatcher(function(\FastRoute\RouteCollector $r)use($container) {
    $r->addRoute('GET', '/', function()use($container){
        if (isset($_GET['project']) && $_GET['project']) {
            $project = $_GET['project'];
        }else{
            $project = $container->config->get('default_project');
        }
    	preg_match('/^([0-9a-zA-Z_.-]+)\/([0-9a-zA-Z_.-]+)@([0-9a-zA-Z_.-]+)/', $project, $res);
        if (isset($_GET['flush']) && $_GET['flush']) {
            $container->cache->delete(md5($res[1] . '/' . $res[2]));
            $container->cache->delete(md5($res[1] . '/' . $res[2] . '@' . $res[3]));
        }
    	echo $container->latte->render(__DIR__ . '/../template/index.html', [
    		'root'=>getRoot(),
    		'user'=>$res[1],
    		'project'=>$res[2],
            'branch'=>$res[3],
    		'home'=>$container->config->get('home')
    	]);
    });
    
    $r->addRoute('GET', '/tags', function()use($container){
        $cache_key = md5($_GET['user'] . '/' . $_GET['project']);
        if (!$tags = $container->cache->fetch($cache_key)) {
            $tags = $container->github->api('gitData')->tags()->all($_GET['user'], $_GET['project']);
            $container->cache->save($cache_key, $tags, $container->config->get('expire'));
        }
        echo json_encode($tags);
    });
    
    $r->addRoute('GET', '/tree', function()use($container){
        $cache_key = md5($_GET['user'] . '/' . $_GET['project'] . '@' . $_GET['branch']);
        if (!$tree = $container->cache->fetch($cache_key)) {
        	$tree = $container->github->api('gitData')->trees()->show($_GET['user'], $_GET['project'], $_GET['branch'], true);
            if ($_GET['branch'] == 'master') {
                $container->cache->save($cache_key, $tree, $container->config->get('expire'));
            }else{
                $container->cache->save($cache_key, $tree);
            }
        }

    	$tmp = [];
    	foreach ($tree['tree'] as $key => $value) {
    		if ($value['type'] != 'blob') {
    			$tmp[] = [
    				'id'=>$value['path'],
    				'parent'=>(dirname($value['path'])=='.')?'#':dirname($value['path']),
    				'text'=>basename($value['path']),
    				'type'=>$value['type']=='blob'?'file':'folder',
    				'icon'=>$value['type']=='blob'?'jstree-file':'jstree-folder',
    				'li_attr'=>$value,
    			];
    		}
    	}
    	foreach ($tree['tree'] as $key => $value) {
    		if ($value['type'] == 'blob') {
    			$tmp[] = [
    				'id'=>$value['path'],
    				'parent'=>(dirname($value['path'])=='.')?'#':dirname($value['path']),
    				'text'=>basename($value['path']),
    				'type'=>$value['type']=='blob'?'file':'folder',
    				'icon'=>$value['type']=='blob'?'jstree-file':'jstree-folder',
    				'li_attr'=>$value,
    			];
    		}
    	}
    	echo json_encode($tmp);
    });

    $r->addRoute('GET', '/blob', function()use($container){
        $cache_key = md5($_GET['user'] . '/' . $_GET['project'] . '@' . $_GET['sha']);
        if (!$blob = $container->cache->fetch($cache_key)) {
        	$blob = $container->github->api('gitData')->blobs()->show($_GET['user'], $_GET['project'], $_GET['sha']);
            $container->cache->save($cache_key, $blob);
        }
        
    	if ($blob['encoding'] == 'base64') {
	    	echo base64_decode($blob['content']);
    	}
    });
});

$routeInfo = $container->dispatcher->dispatch($_SERVER['REQUEST_METHOD'], getUri());

switch ($routeInfo[0]) {
    case \FastRoute\Dispatcher::NOT_FOUND:
        http_response_code(404);
    	echo 'Not Found！';
        break;
    case \FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
        $allowedMethods = $routeInfo[1];
        http_response_code(405);
    	echo 'Not Allowed！';
        break;
    case \FastRoute\Dispatcher::FOUND:
        $container->call($routeInfo[1], $routeInfo[2]);
        break;
}

function getRoot(){
	$root = rawurldecode(pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_DIRNAME));
	return ($root == DIRECTORY_SEPARATOR) ? '' : $root;
}

function getUri(){
	$uri = $_SERVER['REQUEST_URI'];

	if (false !== $pos = strpos($uri, '?')) {
	    $uri = substr($uri, 0, $pos);
	}
	$uri = rawurldecode($uri);

	return substr($uri, strlen(getRoot()));
}